<template>
    <div class="vue-flow-canvas">
        <VueFlow
            v-if="data===undefined"
            v-model="elements.elements"
            :node-types="nodeTypes"
            @connect="connectOperation.onConnect"
            @connect-start="connectOperation.onConnectStart"
            @connect-end="connectOperation.onConnectEnd"
            @edge-context-menu="edgeOperation.edgeContextMenu"
            @node-context-menu="nodeOperation.nodeContextMenu"
        />
        <VueFlow
            v-if="data!==undefined"
            v-model="data"
            :node-types="nodeTypes"
        />
        <!--右键菜单-->
        <n-dropdown
            placement="bottom-start"
            trigger="manual"
            :x="menu.x"
            :y="menu.y"
            :options="menu.options"
            :show="menu.showDropdown"
            :on-clickoutside="menu.onClickOutside"
            @select="menu.handleSelect"
        />
        <!--按钮-->
        <div class="buttonGroup">
            <slot name="buttonGroup"/>
        </div>

    </div>
</template>

<script setup>

import {VueFlow} from "@vue-flow/core";
import {useElementsStore} from "@/stores/elements";
import {markRaw} from "vue";
import {
    AddFile,
    AddPrefixSuffix,
    AreaChart,
    ArimaModel,
    BarChart,
    ChartScatter,
    ChineseParticiple,
    ClassificationCalculation,
    ColumnCombined,
    ConvertDataType,
    Database,
    DataCleaning,
    DataCombined,
    DataDisplay,
    DataExtraction,
    DataReplaced,
    DataSort,
    DataSplit,
    DeleteDuplicate,
    DeleteNullData,
    DeleteRow,
    EditColumn,
    FillMissingData,
    FunnelModel,
    HistogramChart,
    KeyWords,
    KeyWordsExtraction,
    LineChart,
    LogicalJudgment,
    PieChart,
    RadarChart,
    RowColumnConversion,
    Score,
    StripChart,
    TableCleaning,
    TextCleaning,
    TextUpload,
    UserStratificationModel,
    WebUrl,
    WordCloudChart,
    WordFrequency, CalendarHeatMap, ChartBubble, ChartTreemap, Api, FunnelChart, PictureScore, FunnelBModel
} from "@/components/VueFlowModel/Compositions/index";

const props = defineProps(["operable", "data"])
const elements = useElementsStore()
let operable = props.operable === undefined ? true : props.operable
const data = props.data
const nodeTypes = {
    AddFile: markRaw(AddFile),
    DeleteDuplicate: markRaw(DeleteDuplicate),
    DataCombined: markRaw(DataCombined),
    DeleteNullData: markRaw(DeleteNullData),
    Database: markRaw(Database),
    CalendarHeatMap: markRaw(CalendarHeatMap),
    ChartTreemap: markRaw(ChartTreemap),
    ChartBubble: markRaw(ChartBubble),
    ChartScatter: markRaw(ChartScatter),
    Api: markRaw(Api),
    WebUrl: markRaw(WebUrl),
    FillMissingData: markRaw(FillMissingData),
    TableCleaning: markRaw(TableCleaning),
    RowColumnConversion: markRaw(RowColumnConversion),
    BarChart: markRaw(BarChart),
    KeyWords: markRaw(KeyWords),
    WordFrequency: markRaw(WordFrequency),
    LineChart: markRaw(LineChart),
    TextCleaning: markRaw(TextCleaning),
    StripChart: markRaw(StripChart),
    Score: markRaw(Score),
    RadarChart: markRaw(RadarChart),
    PictureScore: markRaw(PictureScore),
    FunnelChart: markRaw(FunnelChart),
    WordCloudChart: markRaw(WordCloudChart),
    ClassificationCalculation: markRaw(ClassificationCalculation),
    UserStratificationModel: markRaw(UserStratificationModel),
    FunnelModel: markRaw(FunnelModel),
    DataSort: markRaw(DataSort),
    DeleteRow: markRaw(DeleteRow),
    EditColumn: markRaw(EditColumn),
    AreaChart: markRaw(AreaChart),
    FunnelBModel: markRaw(FunnelBModel),
    HistogramChart: markRaw(HistogramChart),
    PieChart: markRaw(PieChart),
    ChineseParticiple: markRaw(ChineseParticiple),
    ArimaModel: markRaw(ArimaModel),
    DataDisplay: markRaw(DataDisplay),
    DataSplit: markRaw(DataSplit),
    AddPrefixSuffix: markRaw(AddPrefixSuffix),
    DataCleaning: markRaw(DataCleaning),
    ConvertDataType: markRaw(ConvertDataType),
    DataExtraction: markRaw(DataExtraction),
    DataReplaced: markRaw(DataReplaced),
    ColumnCombined: markRaw(ColumnCombined),
    LogicalJudgment: markRaw(LogicalJudgment),
    KeyWordsExtraction: markRaw(KeyWordsExtraction),
    TextUpload: markRaw(TextUpload),
}

// 柄的操作
const connectOperation = {
    onConnectStart: ({nodeId, handleType}) => {
        // 点击柄
        if (!operable) {
            return
        }
        if (handleType === 'target') {
            window.$message.warning("这是被接入口");
        }
        return console.log('on connect start', {nodeId, handleType});
    },
    onConnect: (params) => {
        // 链接柄
        if (!operable) {
            return
        }
        console.log('on connect', params)
        // 源组件下标
        let aNumber = null
        // 入组件下标
        let bNumber = null
        // 判断接入接出的最大数
        for (let i in elements.elements) {
            if (elements.elements[i].id === params.source) {
                aNumber = i
            } else if (elements.elements[i].id === params.target) {
                bNumber = i
            } else if (aNumber !== null && bNumber !== null) {
                break
            }
        }
        if (elements.elements[aNumber].maxExportNumber > 0 && elements.elements[bNumber].maxEntryNumber > 0) {
            // 组件连接数都有剩余---添加线
            elements.addEdge({
                id: "edge-" + params.source + "-" + params.target,
                type: "edge",
                class: "edge",
                animated: true,
                ...params
            });
            elements.elements[aNumber].maxExportNumber--
            elements.elements[bNumber].maxEntryNumber--
            return;
        }
        window.$message.warning("组件连接数已达到最大")
    },
    onConnectEnd: (event) => {
        // 松开柄
        if (!operable) {
            return
        }
        return console.log('on connect end', event)
    }
}
// 线的操作
const edgeOperation = {
    edgeContextMenu: ({edge, event}) => {
        // 线的右键事件
        if (!operable) {
            return
        }
        menu.handleContextMenu(event, edge)// 打开右键菜单
    },
}

// 节点的操作
const nodeOperation = {
    nodeContextMenu: ({node, event}) => {
        // 节点的右键事件
        if (!operable) {
            return
        }
        menu.handleContextMenu(event, node)// 打开右键菜单
    }
}

// 菜单
const menu = reactive({
    showDropdown: false,
    x: 0,
    y: 0,
    data: null,
    // 选中菜单项目
    handleSelect: (key) => {
        menu.showDropdown = false
        // 菜单操作
        const del = () => {
            // 删除
            if (menu.data['class'] === 'edge') {
                elements.delEdge(menu.data)
            } else if (menu.data['class'] === 'node') {
                elements.delNode(menu.data)
            }
        }
        const copy = () => {
            if (menu.data['class'] === 'edge') {
                window.$message.info("复制线干嘛呢?")
            } else if (menu.data['class'] === 'node') {
                let x = menu.data.position.x + 100
                let y = menu.data.position.y
                elements.addElements(elements.getElementTemplate(menu.data.type, x,y))
                console.log(menu.data)
            }
        }
        const operation = {del, copy}
        operation[key]()
    },
    // 打开右键菜单
    handleContextMenu: (event, edge) => {
        event.preventDefault() // 阻止默认事件
        menu.showDropdown = false
        nextTick().then(() => {
            menu.showDropdown = true
            menu.data = edge
            menu.x = event.clientX
            menu.y = event.clientY
        })
    },
    // 点击外部
    onClickOutside: () => {
        menu.showDropdown = false
    },
    options: [
        {label: "复制组件", key: "copy"},
        {label: "删除", key: "del"},
    ]
})

</script>

<style scoped lang="less">
.buttonGroup {
    position: absolute;
    bottom: 40px;
    right: 100px;
}
</style>